package com.yc.http.tomcat.impl;

import com.yc.http.tomcat.Cookie;
import com.yc.http.tomcat.HttpServletResponse;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpServletResponseImpl implements HttpServletResponse {

    private OutputStream out;
    private int status = 200;  // 结果码
    private String msg = "OK";  // 结果码描述
    StringWriter sw;     // 保存 servlet 输出的内容
    private Map<String,String> headerMap = new HashMap<>();

    public HttpServletResponseImpl(Socket socket) throws IOException {
        out = socket.getOutputStream();
    }

    @Override
    public PrintWriter getWriter() {
        /**
         * 流的分类
         * 方向: 输入流(Inputxxx, xxxReader), 输出流(Outputxxx, xxxWriter)
         * 格式: 字节流(xxxStream)   字符流(xxxWriter,xxxReader)
         * 处理: 资源流(构造函数是资源 file),    处理流(构造函数参数是另一个流)
         */
        sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        return pw;
    }

    @Override
    public OutputStream getOutputStream() {
        return out;
    }

    @Override
    public void setContentType(String type) {
        headerMap.put("Content-Type", type);
    }

    @Override
    public void setStatus(int status, String msg) {
        // 官方该方法已经被废弃, 推荐使用 setStatus(int status)
        this.status = status;
        this.msg = msg;
    }

    @Override
    public void setHeader(String name, String value) {
        headerMap.put(name,value);
    }

    @Override
    public void flushBuffer() {
        try{
            out.write(("HTTP/1.1 "+status+" "+msg+"\n").getBytes());
            // 响应体的格式说明
            for (Map.Entry<String, String> en : headerMap.entrySet()) {
                String s = "%s: %s\n";
                String line = String.format(s, en.getKey(), en.getValue());
                out.write(line.getBytes());
            }
            // 将cookie写入响应头中
            for (Cookie cookie : cookieList) {
                out.write(cookie.toString().getBytes());
            }
            // 空行
            out.write("\n".getBytes());
            if(sw!=null){
                // 响应体 body
                out.write(sw.toString().getBytes());
            }
        } catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendRedirect(String location) {
        setStatus(301, "Location");
        setHeader("Location", location);
    }

    List<Cookie> cookieList = new ArrayList<>();
    @Override
    public void addCookie(Cookie cookie) {
        cookieList.add(cookie);
    }
}
